<?php

namespace Lib;

use RedBean_Facade as R;

class MyHelper
{
    // @todo $app->request->isAjax()
    // @todo 如果是ajax请求，不是redirect而是输出json，格式化的json响应
    
    /**
     * 授权完回调的route
     * 
     * @var string
     */
    private $authRoute = 'index';
    
    /**
     * 针对没有用户授权的应用
     * 设置一个UUID到cookie中对用户进行追踪
     */
    public function customUserTrack()
    {
        $app = \Slim\Slim::getInstance();
        
        $uuid = $app->getCookie('uuid');
        if ($uuid) {
            $user = R::findOne('user', ' uuid = ? ', [ $uuid ]);
            if ($user) {
                $app->user = $user;
            }
            return;
        }
        
        $now = time();
        $uuid = md5(uniqid() . $now) . $now;
        $app->setCookie('uuid', $uuid);
    }
    
    private function getWxAuthUrl() {
        $app = \Slim\Slim::getInstance();
        return WxHelper::getAuthUrl($this->authRoute, $app->config('wxscope'));
    }
    
    /**
     * 当前用户必须已经存在，如果没有则需要去授权后回来创建
     * 授权部分请使用authCallback middleware
     */
    public function userRequired(\Slim\Route $route)
    {
        $app = \Slim\Slim::getInstance();
        
        $wxAuthUrl = $this->getWxAuthUrl();
        $uuid = $app->getCookie('uuid');
        if ($uuid) {
            $user = R::findOne('user', ' uuid = ? ', [ $uuid ]);
            if (!$user) {
                $app->deleteCookie('uuid');
                $app->redirect($wxAuthUrl);
            }
            
            $app->user = $user;
        } else if ($route->getName() != $this->authRoute) {
            // 防止循环
            $app->redirect($wxAuthUrl);
        }
    }
    
    /**
     * 95589授权跳转
     * @todo 如何将第三方授权抽象出来，未来模仿微信授权进行测试
     */
    public function tpuserRequired(\Slim\Route $route)
    {
        $authBase = 'http://116.228.52.92/wxqhb/playGame.html?sendUrl=';
        $app = \Slim\Slim::getInstance();
        $baseUrl = $app->config('base_url') ? $app->config('base_url') : $app->request->getUrl();
        $callbackUrl =  $route->getName() == 'friend' ? $app->urlFor('friend', $route->getParams()) : $app->urlFor($this->authRoute);
        $authUrl = $authBase . urlencode($baseUrl . $callbackUrl);
        
        $uuid = $app->getCookie('uuid');
        if ($uuid) {
            $user = R::findOne('user', ' uuid = ? ', [ $uuid ]);
            if (!$user) {
                $app->deleteCookie('uuid');
            } else {
                $app->user = $user;
                return;
            }
        }
        
        if (isset($_SERVER['HTTP_HOST']) && ($_SERVER['HTTP_HOST'] == 'localhost' || $_SERVER['HTTP_HOST'] == '10.0.3.2')) {
            $userinfo =[
                'nickname'   => uniqid('u_'),
                'headimgurl' => 'http://baidu.com',
                'openid'     => uniqid('wx_')
            ];
        } else {
            $userinfo = $app->request->post('userinfo');
            if (!$userinfo) {
                $fp = fopen('app/cache/my.log', "a");
                fwrite($fp, "auth failed \r\n");
                fclose($fp);
                $app->redirect($authUrl);
            }

            $userinfo = json_decode($userinfo, true);
            
            if (!isset($userinfo['openid'])) {
                $fp = fopen('app/cache/my.log', "a");
                fwrite($fp, $userinfo . "\r\n");
                fclose($fp);
                $app->redirect($authUrl);
            }
        }
        
        $openid = $userinfo['openid'];
        $user = R::findOne('user', ' openid = ? ', [ $openid ]);
        if (!$user) {
            $user = R::dispense('user');
            $user->openid = $openid;
            $user->nick = $userinfo['nickname'];
            $user->head = $userinfo['headimgurl'];
            $user->uuid = md5($openid) . time();
            $user->createdAt = R::isoDateTime();

            $app->applyHook('user.before.create', $user);
            R::store($user);
            $app->applyHook('user.after.create', $user);

            $app->setCookie('uuid', $user->uuid);
            $app->user = $user;
        }
    }
    
    /**
     * 用户访问了别人分享的链接，即发现该链接的uid和自己的uid不同
     * 就需要创建这个好友关系
     * 
     * @dependency userRequired
     * @todo how to specify dependencies and the order
     */
    public function friendVisitable(\Slim\Route $route)
    {
        $app = \Slim\Slim::getInstance();
        if (!$app->user) return;
        
        $user = $app->user;
        $uuid = $app->request->get('uuid'); // 分享链接的用户或者当前用户
        
        // refactor to move this out
        if ($uuid && $uuid != $user->uuid) {
            // 被访问的是别人(uuid)分享出来的
            $app->redirect($app->urlFor('friend', ['uuid' => $uuid]) . '?uuid=' . $user->uuid);
            exit;
        }
        
        // @todo ?此要求分享者uuid一定要被设置为route parameter
        $routeParams = $route->getParams();
        if (!isset($routeParams['uuid']) || $routeParams['uuid'] == $user->uuid) { // /xxx/:uuid
            $app->redirect($app->urlFor('index'));
            exit;
        }
        
        $fuuid = $routeParams['uuid'];
        $friend = R::findOne('user', ' uuid = ? ', [ $fuuid ]);
        if (!$friend) {
            return;
        }
        $app->friend = $friend;
        $friendship = R::findOne('friendship','uid = ? AND fid = ?',[ $friend->id, $user->id ]);
        if (!$friendship){
            // 当前用户是该用户的好友
            $friendship = R::dispense('friendship');
            $friendship->uid = $friend->id;
            $friendship->fid = $user->id;
            
            $app->applyHook('friendship.before.create', $friendship);
            R::store($friendship);
            $app->applyHook('friendship.after.create', $friendship);
        }
    }
    
    /**
     * 微信授权回调触发
     */
    public function authCallback()
    {
        $app = \Slim\Slim::getInstance();
        if ($app->user) return;
        
        $wxAuthUrl = $this->getWxAuthUrl();
        
        $code = $app->request->get('code');
        if (!$code) {
            $app->redirect($wxAuthUrl);
        }

        // 授权回来
        $userinfo = WxHelper::getUserInfo($code, $app->config('wxscope'));
        if ($userinfo === false) {
            $app->redirect($wxAuthUrl);
        }
        $openid = $userinfo['openid'];
        $user = R::findOne('user', ' openid = ? ', [ $openid ]);
        if (!$user) {
            $user = R::dispense('user');
            $user->openid = $openid;
            $user->nick = $userinfo['nick'];
            $user->head = $userinfo['head'];
            $user->uuid = md5($openid) . time(); // 设置uuid防止被猜出用户id或者泄露用户openid
            $user->createdAt = R::isoDateTime();

            $app->applyHook('user.before.create', $user);
            R::store($user);
            $app->applyHook('user.after.create', $user);
        }
        
        $app->setCookie('uuid', $user->uuid);
        $app->user = $user;
    }
}